home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / djgpp / contrib / pdcurs22 / src / portable / getch.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-26  |  9.2 KB  |  341 lines

  1. /*
  2. ***************************************************************************
  3. * This file comprises part of PDCurses. PDCurses is Public Domain software.
  4. * You may use this code for whatever purposes you desire. This software
  5. * is provided AS IS with NO WARRANTY whatsoever.
  6. * Should this software be used in another application, an acknowledgement
  7. * that PDCurses code is used would be appreciated, but is not mandatory.
  8. *
  9. * Any changes which you make to this software which may improve or enhance
  10. * it, should be forwarded to the current maintainer for the benefit of 
  11. * other users.
  12. *
  13. * The only restriction placed on this code is that no distribution of
  14. * modified PDCurses code be made under the PDCurses name, by anyone
  15. * other than the current maintainer.
  16. * See the file maintain.er for details of the current maintainer.
  17. ***************************************************************************
  18. */
  19. #define    CURSES_LIBRARY    1
  20. #include <curses.h>
  21.  
  22. /* undefine any macros for functions defined in this module */
  23. #undef    getch
  24. #undef    wgetch
  25. #undef    mvgetch
  26. #undef    mvwgetch
  27. #undef    ungetch
  28.  
  29. /* undefine any macros for functions called by this module if in debug mode */
  30. #ifdef PDCDEBUG
  31. #  undef    wrefresh
  32. #  undef    nocbreak
  33. #  undef    move
  34. #  undef    wmove
  35. #endif
  36.  
  37. #ifdef PDCDEBUG
  38. char *rcsid_getch  = "$Id$";
  39. #endif
  40.  
  41. /*man-start*********************************************************************
  42.  
  43.   Name:                                                         getch
  44.  
  45.   Synopsis:
  46.       int getch(void);
  47.       int wgetch(WINDOW *win);
  48.       int mvgetch(int y, int x);
  49.       int mvwgetch(WINDOW *win, int y, int x);
  50.       int ungetch(int ch);
  51.  
  52.   X/Open Description:
  53.      With the getch(), wgetch(), mvgetch(), and mvwgetch() functions, 
  54.      a character is read from the terminal associated with the window. 
  55.      In nodelay mode, if there is no input
  56.      waiting, the value ERR is returned. In delay mode, the program will
  57.      hang until the system passes text through to the program.
  58.      Depending on the setting of cbreak(), this will be after one
  59.      character or after the first newline.  Unless noecho() has
  60.      been set, the character will also be echoed into the designated
  61.      window.
  62.  
  63.      If keypad() is TRUE, and a function key is pressed, the token for
  64.      that function key will be returned instead of the raw characters.
  65.      Possible function keys are defined in <curses.h> with integers
  66.      beginning with 0401, whose names begin with KEY_.  If a character
  67.      is received that could be the beginning of a function key (such as
  68.      escape), curses will set a timer.  If the remainder of the sequence
  69.      does not come in within the designated time, the character will be
  70.      passed through, otherwise the function key value will be returned.
  71.      For this reason, on many terminals, there will be a delay after a
  72.      user presses the escape key before the escape is returned to the
  73.      program.  (Use by a programmer of the escape key for a single
  74.      character function is discouraged.)
  75.  
  76.      If nodelay(win,TRUE) has been called on the window and no input is
  77.      waiting, the value ERR is returned.
  78.  
  79.      The ungetch() function places ch back onto the input queue to be
  80.      returned by the next call to wgetch().
  81.  
  82.      NOTE: getch(), mvgetch() and mvwgetch() are implemented as macros.
  83.  
  84.   PDCurses Description:
  85.      Given the nature of the PC, there is no such timer set for an
  86.      incoming ESCAPE value, because function keys generate unique
  87.      scan codes that are not prefixed with the ESCAPE character.
  88.  
  89.      Also, note that the getch() definition will conflict  with
  90.      many DOS compiler's runtime libraries.
  91.  
  92.   X/Open Return Value:
  93.      This functions return ERR or the value of the character, meta 
  94.      character or function key token.
  95.  
  96.   X/Open Errors:
  97.      No errors are defined for this function.
  98.  
  99.   Portability                             X/Open    BSD    SYS V
  100.                                           Dec '88
  101.       getch                                 Y        Y       Y
  102.       wgetch                                Y        Y       Y
  103.       mvgetch                               Y        Y       Y
  104.       mvwgetch                              Y        Y       Y
  105.       ungetch                               Y        Y       Y
  106.  
  107. **man-end**********************************************************************/
  108.  
  109. static WINDOW *w;            /* to reduce stack usage   */
  110.  
  111. /* this define to get around DOS libraries conflict */
  112. #define getch PDC_getch
  113. /***********************************************************************/
  114. int    PDC_getch(void)
  115. /***********************************************************************/
  116. {
  117. #ifdef PDCDEBUG
  118.     if (trace_on) PDC_debug("getch() - called\n");
  119. #endif
  120.  
  121.     if (stdscr == (WINDOW *)NULL)
  122.         return( ERR );
  123.  
  124.     return(wgetch(stdscr));
  125. }
  126. /***********************************************************************/
  127. int    wgetch(WINDOW *win)
  128. /***********************************************************************/
  129. {
  130. extern    int    c_pindex;        /* putter index           */
  131. extern    int    c_gindex;        /* getter index           */
  132. extern    int    c_ungind;        /* ungetch() push index   */
  133. extern    int    c_ungch[NUNGETCH];    /* array of ungotten chars */
  134. extern  WINDOW*    _getch_win_;
  135.  
  136. /*    signed    key; MH*/
  137.     int    key;
  138.     bool    cbr;
  139. /*    static    chtype    buffer[_INBUFSIZ];MH*/    /* character buffer */
  140.     static    int    buffer[_INBUFSIZ];    /* character buffer */
  141. #ifdef UNIX
  142.     short display_key = 0400;
  143.     bool cbreak_set = FALSE;
  144. #else
  145.     short display_key = 0x100;
  146. #endif
  147.  
  148. #ifdef PDCDEBUG
  149.     if (trace_on) PDC_debug("wgetch() - called\n");
  150. #endif
  151.  
  152.     if (win == (WINDOW *)NULL)
  153.         return( ERR );
  154.  
  155. /* wrs (7/31/93) -- System V curses refreshes window when wgetch is called */
  156. /*                  if there have been changes to it and it is not a pad */
  157.     if( (! (win->_flags & _PAD)) && (! win->_nodelay) ) 
  158.     {
  159.         if( is_wintouched(win) )
  160.             wrefresh(win);
  161.     }
  162.  
  163.     _getch_win_ = win;
  164.  
  165.     if (c_ungind)    
  166.     {            /* if ungotten char exists */
  167.                         /* remove and return it */
  168.         if ((! (win->_flags & _PAD)) && (win->_nodelay))
  169.         {
  170.             if ( is_wintouched(win) )
  171.                 wrefresh(win);
  172.         }
  173.         return( c_ungch[--c_ungind] );
  174.     }
  175.  
  176.     if ((!_cursvar.raw_inp) && (!_cursvar.cbreak))
  177.     {
  178.         /*
  179.          * if normal
  180.          */
  181.         if (c_gindex < c_pindex)
  182.         {
  183.             /*
  184.              * and data in buffer
  185.              */
  186.             return( buffer[c_gindex++] );
  187.         }
  188.     }
  189.  
  190.     w = win;        /* static for speed & stack */
  191.     c_pindex = 0;        /* prepare to buffer data */
  192.     c_gindex = 0;
  193.  
  194.     for(;;)            /* loop for any buffering */
  195.     {
  196.  
  197. #ifdef UNIX
  198.         if (!(_cursvar.raw_inp || _cursvar.cbreak))
  199.             {
  200.             cbreak();
  201.             cbreak_set = TRUE;
  202.             }
  203.         if (w->_use_keypad)
  204.             key = PDC_sysgetch();
  205.         else
  206.             key = PDC_rawgetch();
  207.         if (cbreak_set)
  208.             nocbreak();
  209. #endif
  210.  
  211. #if defined(DOS) || defined(OS2)
  212.         if (_cursvar.raw_inp)
  213.         {
  214.             /*
  215.              * get a raw character
  216.              */
  217.             key = PDC_rawgetch();
  218.         }
  219.         else
  220.         {
  221.             /*
  222.              * get a system character
  223.              * if break return proper
  224.              */
  225.             cbr = PDC_get_ctrl_break();
  226.             PDC_set_ctrl_break(_cursvar.orgcbr);
  227.             key = PDC_sysgetch();
  228.             PDC_set_ctrl_break(cbr);    /* restore as it was */
  229.         }
  230. #endif
  231.  
  232. #if defined(XCURSES)
  233.     key = PDC_rawgetch();
  234. #endif
  235.  
  236.         if (w->_nodelay)
  237.         {
  238.             /*
  239.              * if nodelay and no char
  240.              */
  241.             if (key == -1)
  242.                 return( ERR );
  243.             else if ( ! _cursvar.echo ) {
  244.                 if( ! (w->_flags & _PAD) ) {
  245.                     if( is_wintouched(w) )
  246.                         wrefresh(w);
  247.                 }
  248.             }
  249.         }
  250.         if ((key == '\r') &&
  251.             (_cursvar.autocr) &&
  252.             (!_cursvar.raw_inp))
  253.         {
  254.             /*
  255.              * translate CR
  256.              */
  257.             key = '\n';
  258.         }
  259.         if (_cursvar.echo && (key < display_key))
  260.         {
  261.             /*
  262.              * if echo is enabled
  263.              */
  264.             waddch(w, key);
  265.             wrefresh(w);
  266.         }
  267.         if (_cursvar.raw_inp || _cursvar.cbreak)
  268.         {
  269.             /*
  270.              * if no buffering
  271.              */
  272.             return( key );
  273.         }
  274.  
  275.         if (c_pindex < _INBUFSIZ - 2)
  276.         {
  277.             /*
  278.              * if no overflow, put data in buffer
  279.              */
  280.             buffer[c_pindex++] = key;
  281.         }
  282.         if ((key == '\n') || (key == '\r'))
  283.         {
  284.             /*
  285.              * if we got a line
  286.              */
  287.             return( buffer[c_gindex++] );
  288.         }
  289.     }
  290. }
  291. /***********************************************************************/
  292. int    mvgetch(int y, int x)
  293. /***********************************************************************/
  294. {
  295. #ifdef PDCDEBUG
  296.     if (trace_on) PDC_debug("mvgetch() - called\n");
  297. #endif
  298.  
  299.     if (stdscr == (WINDOW *)NULL)
  300.         return( ERR );
  301.  
  302.     if (move(y, x) == ERR)
  303.         return(ERR);
  304.     return(getch());
  305. }
  306. /***********************************************************************/
  307. int    mvwgetch(WINDOW *win, int y, int x)
  308. /***********************************************************************/
  309. {
  310. #ifdef PDCDEBUG
  311.     if (trace_on) PDC_debug("mvwgetch() - called\n");
  312. #endif
  313.  
  314.     if (win == (WINDOW *)NULL)
  315.         return( ERR );
  316.  
  317.     if (wmove(win,y, x) == ERR)
  318.         return(ERR);
  319.     return(wgetch(win));
  320. }
  321. /***********************************************************************/
  322. int    ungetch(int ch)
  323. /***********************************************************************/
  324. {
  325. extern    int    c_pindex;        /* putter index */
  326. extern    int    c_gindex;        /* getter index */
  327. extern    int    c_ungind;        /* ungetch() push index */
  328. extern    int    c_ungch[NUNGETCH];    /* array of ungotten chars */
  329.  
  330. #ifdef PDCDEBUG
  331.     if (trace_on) PDC_debug("ungetch() - called\n");
  332. #endif
  333.  
  334.     if (c_ungind >= NUNGETCH)    /* pushback stack full */
  335.         return( ERR );
  336.  
  337.     c_ungch[c_ungind++] = ch;
  338.     return( OK );
  339. }
  340.